import { ElForm, ElFormItem,FormItemRule ,ElCol,ElRow} from "element-plus"
import { Ref, reactive, ref } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'
import { CommonOption, FN } from "@Tea/model"
import { renderElement ,ElementType, InputAttrType, SlotType} from "@/hooks/useElementFormItem"

type BaseContentType<T extends object = {}> = {
    span?: number,
    label: string,
    
    feild: T extends Ref<any> ? "value" : keyof T,
    labelWidth?: string,
}
export type FormContentType<T extends object = {}> = Array<
  ({
    type:  "text"
    attr?: InputAttrType
  } & BaseContentType<T>)
  |({
    type:  "select"
    attr?: InputAttrType
    option: CommonOption[] | Ref<CommonOption[]>
  } & BaseContentType<T>) | {
    type: 'slot'
    VNode: () => JSX.Element
  } & BaseContentType<T>
>

export type renderFormType<T extends object = {}> = {
  ruleForm: T, // form 表单对象
  rules?: {
    [K in keyof T] ?: FormItemRule[]
  }, // 规则
  labelWidth?: string,
  class?: string,
  content: FormContentType<T>[]
}
export const renderForm = function <T extends object = {}>(config: renderFormType<T>) {
  const ruleFormRef = ref<FormInstance>()
  const ruleForm = config.ruleForm
  const rules = reactive<FormRules>(config.rules)

  // 点击确定
  const submitForm = async (callBack: FN) => {
    if (!ruleFormRef.value) return
    await ruleFormRef.value.validate((valid, fields) => {
      if (valid) {
        callBack?.()
      } else {
        console.log('error submit!', fields)
      }
    })
  }

  const resetForm = () => {
    if (!ruleFormRef.value) return
    ruleFormRef.value.resetFields()
  }

  // 整个form 组件
  const Form = () => (
    <ElForm
      ref={ruleFormRef}
      model={ruleForm}
      rules={rules}
      label-width={config.labelWidth || "5rem"}
      class={config.class || ""}
    >
      {
        config.content.map(((r, index) => (
          <ElRow key={index}>
            {r.map((c, i) => (
              <ElCol key={i} span={c.span || 4}>
                <ElFormItem label={c.label} labelWidth={c.labelWidth || config.labelWidth} prop={c.feild as string}>
                  {renderElement(c.type === 'slot' ? { ...c } : { ...c, vModel: ruleForm as typeof config.ruleForm })}
                </ElFormItem>
              </ElCol>
            ))}
          </ElRow>
        )))
      }
    </ElForm>
  )

  return { Form, submitForm, resetForm }
}